﻿using System;
using System.Drawing;
using System.Globalization;

using Microsoft.WindowsMobile.Status;

using iPhoneUI.Shell;

namespace iPhoneUI.Widgets
{
    public class TopBar : TextWidget
    {
        private Bitmap m_topLock;
        private Bitmap m_topunLock;

        private Bitmap m_signalLevel;
        private Bitmap m_batteryLevel;

        private Bitmap m_gprsImage;
        private IImage m_bluetoothImage;

        private Rectangle m_signalStrengthRectangle;
        private Rectangle m_batterLevelRectangle;
        private Rectangle m_middleRectangle;
        private Rectangle m_bluetoothRectangle;

        public TopBar()
        {
            Font = ShellConfig.CreateFont(8, FontStyle.Regular);

            m_topLock = ShellConfig.CreateImage("toplock.bmp");
            m_topunLock = ShellConfig.CreateImage("topunlock.bmp");
            m_gprsImage = ShellConfig.CreateImage("gprs.bmp");
            m_bluetoothImage = ShellConfig.CreatePerPixelAlphaImage("bluetooth.png");
        }

        protected override void OnSetOwner()
        {
            m_signalLevel = GetPhoneSignalImage();
            m_batteryLevel = GetBatteryImage();
            SetInitialSize(new Size(Owner.Width, m_signalLevel.Height));

            RegisterSystemStateChange(SystemProperty.PowerBatteryStrength);
            RegisterSystemStateChange(SystemProperty.PowerBatteryState);

            RegisterSystemStateChange(SystemProperty.PhoneSignalStrength);
            RegisterSystemStateChange(SystemProperty.PhoneRadioOff);
            RegisterSystemStateChange(SystemProperty.PhoneNoService);
            RegisterSystemStateChange(SystemProperty.PhoneSearchingForService);
            RegisterSystemStateChange(SystemProperty.PhoneRoaming);
            RegisterSystemStateChange(SystemProperty.PhoneOperatorName);

            RegisterSystemStateChange(SystemProperty.BluetoothStatePowerOn);

            RegisterSystemStateChange(SystemProperty.CellularSystemAvailable1xrtt);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableEdge);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableEvdo);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableEvdv);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableGprs);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableHsdpa);
            RegisterSystemStateChange(SystemProperty.CellularSystemAvailableUmts);

            Layout();

            base.OnSetOwner();
        }

        protected override void Layout()
        {
            m_signalStrengthRectangle = new Rectangle(Location.X, Location.Y, m_signalLevel.Width, m_signalLevel.Height);
            m_signalStrengthRectangle.Size = Owner.ScaleSize(m_signalStrengthRectangle.Size);

            m_batterLevelRectangle = new Rectangle(0, 0, m_batteryLevel.Width, m_batteryLevel.Height);
            m_batterLevelRectangle.Size = Owner.ScaleSize(m_batterLevelRectangle.Size);
            m_batterLevelRectangle.X = Size.Width - m_batterLevelRectangle.Width;

            int middleWidth = Owner.Width - m_signalStrengthRectangle.Width - m_batterLevelRectangle.Width;
            m_middleRectangle = new Rectangle(m_signalStrengthRectangle.Width, Location.Y, middleWidth, Size.Height);

            Size size = Owner.ScaleSize(m_bluetoothImage.Size());
            m_bluetoothRectangle = new Rectangle(m_batterLevelRectangle.X - size.Width, Location.Y + 2, size.Width, size.Height);

            base.Layout();
        }

        protected override void OnSystemStateChanged(SystemState property, object newValue)
        {
            switch (property.Property)
            {
                case SystemProperty.PowerBatteryState:
                case SystemProperty.PowerBatteryStrength:
                    m_batteryLevel.SafeDispose();
                    m_batteryLevel = GetBatteryImage();
                    break;

                case SystemProperty.PhoneSignalStrength:
                case SystemProperty.PhoneRadioOff:
                case SystemProperty.PhoneNoService:
                case SystemProperty.PhoneSearchingForService:
                    m_signalLevel.SafeDispose();
                    m_signalLevel = GetPhoneSignalImage();

                    break;
            }

            base.OnSystemStateChanged(property, newValue);
        }

        protected override void OnDispose()
        {
            m_topLock.SafeDispose();
            m_topunLock.SafeDispose();
            m_batteryLevel.SafeDispose();
            m_signalLevel.SafeDispose();
            m_gprsImage.SafeDispose();

            m_bluetoothImage = null;

            base.OnDispose();
        }

        public bool Locked { get; set; }

        protected override void OnDraw(Canvas canvas, Rectangle clipBounds)
        {
            if (m_signalStrengthRectangle.IntersectsWith(clipBounds))
                canvas.AlphaBlend(m_signalLevel, 200, m_signalStrengthRectangle, Rectangle.FromLTRB(0, 0, m_signalLevel.Width, m_signalLevel.Height));

            if (m_middleRectangle.IntersectsWith(clipBounds))
            {
                int paddedY = Owner.ScaleY(Location.Y + 2);
                canvas.AlphaBlend(m_topunLock, 200, m_middleRectangle, Rectangle.FromLTRB(0, 0, m_topunLock.Width, m_topunLock.Height));
                using (Brush b = new SolidBrush(ForeColor))
                {
                    if (Locked)
                    {
                        Rectangle rect = new Rectangle((ClientArea.Width / 2) - (m_topLock.Width / 2), (Size.Height / 2) - (m_topLock.Height / 2), m_topLock.Width, m_topLock.Height);
                        rect.Size = Owner.ScaleSize(rect.Size);

                        canvas.AlphaBlend(m_topLock, 200, rect, Rectangle.FromLTRB(0, 0, m_topLock.Width, m_topLock.Height));
                    }
                    else
                    {
                        string time = DateTime.Now.ToString(CultureInfo.CurrentUICulture.DateTimeFormat.ShortTimePattern, CultureInfo.CurrentUICulture);
                        canvas.DrawString(time, Font, b, CenterString(time, Font, canvas), paddedY);
                    }

                    string carrier = GetCarrierString();
                    SizeF size = canvas.MeasureString(carrier, Font);
                    canvas.DrawString(carrier, Font, b, m_signalStrengthRectangle.Right + 1, paddedY);

                    if (DataNetworkAvailable)
                        canvas.AlphaBlend(m_gprsImage, 200, m_signalStrengthRectangle.Right + 3 + (int)size.Width, CenterOn(Size.Height, m_gprsImage.Height));
                }

                if (SystemState.BluetoothStatePowerOn)
                    canvas.AlphaBlend(m_bluetoothImage, m_bluetoothRectangle);
            }

            if (m_batterLevelRectangle.IntersectsWith(clipBounds))
                canvas.AlphaBlend(m_batteryLevel, 200, m_batterLevelRectangle, Rectangle.FromLTRB(0, 0, m_batteryLevel.Width, m_batteryLevel.Height));
        }

        private static string GetCarrierString()
        {
            if (SystemState.PhoneRoaming)
                return "Roaming";

            return SystemState.PhoneOperatorName;
        }

        private static Bitmap GetPhoneSignalImage()
        {
            if (SystemState.PhoneRadioOff)
                return ShellConfig.CreateImage("airplane.bmp");

            if (SystemState.PhoneSearchingForService)
                return ShellConfig.CreateImage("searchingforservice.bmp");

            if (SystemState.PhoneNoService)
                return ShellConfig.CreateImage("SignalLevelVeryLow2.bmp");

            int strength = SystemState.PhoneSignalStrength;
            if (strength > 80)
                return ShellConfig.CreateImage("SignalLevelVeryHigh.bmp");

            if (strength > 60)
                return ShellConfig.CreateImage("SignalLevelHigh.bmp");

            if (strength > 50)
                return ShellConfig.CreateImage("SignalLevelMedium.bmp");

            if (strength > 20)
                return ShellConfig.CreateImage("SignalLevelLow.bmp");

            return ShellConfig.CreateImage("SignalLevelVeryLow1.bmp");
        }

        private static Bitmap GetBatteryImage()
        {
            if(SystemState.PowerBatteryState == BatteryState.Charging)
                return ShellConfig.CreateImage("batterycharging.bmp");

            switch (SystemState.PowerBatteryStrength)
            {
                case BatteryLevel.VeryHigh:
                    return ShellConfig.CreateImage("BatteryLevelVeryHigh.bmp");

                case BatteryLevel.High:
                    return ShellConfig.CreateImage("BatteryLevelHigh.bmp");

                case BatteryLevel.Medium:
                    return ShellConfig.CreateImage("BatteryLevelMedium.bmp");

                case BatteryLevel.Low:
                    return ShellConfig.CreateImage("BatteryLevelLow.bmp");

                case BatteryLevel.VeryLow:
                    return ShellConfig.CreateImage("BatteryLevelVeryLow1.bmp");
            }

            return null;
        }

        private static bool DataNetworkAvailable
        {
            get
            {
                return SystemState.CellularSystemAvailable1xrtt ||
                        SystemState.CellularSystemAvailableEdge ||
                        SystemState.CellularSystemAvailableEvdo ||
                        SystemState.CellularSystemAvailableEvdv ||
                        SystemState.CellularSystemAvailableGprs ||
                        SystemState.CellularSystemAvailableHsdpa ||
                        SystemState.CellularSystemAvailableUmts;
            }
        }
    }
}